use std::future::Future;
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use tokio::runtime::{Builder, Runtime};
use tokio::task;
use tokio::time::sleep;

/// 运行工具
///
/// @since 2.0
pub struct RunUtils {
    /// 异步执行器（一般用于异步任务）
    single_executor: Arc<Runtime>,
    /// 异步执行器（一般用于异步任务）
    async_executor: Arc<Runtime>,
    /// 调度执行器（一般用于延时任务）
    scheduled_executor: Arc<Runtime>,
}

impl RunUtils {
    pub fn new() -> Self {
        let single_executor = Arc::new(Runtime::new().unwrap());

        let async_pool_size = std::cmp::max(num_cpus::get(), 2);
        let async_executor = Arc::new(
            Builder::new_multi_thread()
                .worker_threads(async_pool_size)
                .build()
                .unwrap(),
        );

        let scheduled_executor = Arc::new(Runtime::new().unwrap());

        RunUtils {
            single_executor,
            async_executor,
            scheduled_executor,
        }
    }

    pub fn set_scheduled_executor(&mut self, scheduled_executor: Arc<Runtime>) {
        self.scheduled_executor = scheduled_executor;
        // Rust的executor会在所有任务完成后自动关闭，所以这里不需要手动关闭
    }

    pub fn get_scheduled_executor(&self) -> Arc<Runtime> {
        Arc::clone(&self.scheduled_executor)
    }

    pub fn set_async_executor(&mut self, async_executor: Arc<Runtime>) {
        self.async_executor = async_executor;
        // Rust的executor会在所有任务完成后自动关闭，所以这里不需要手动关闭
    }

    pub fn run_and_try<F>(task: F)
    where
        F: FnOnce() + Send + 'static,
    {
        match std::panic::catch_unwind(std::panic::AssertUnwindSafe(task)) {
            Ok(_) => {}
            Err(_) => {
                // 略...
            }
        }
    }

    /// 异步执行（单线程）
    pub async fn single<F>(&self, task: F) -> Result<(), Box<dyn std::error::Error>>
    where
        F: Future<Output = ()> + Send + 'static,
    {
        self.single_executor.spawn(task).await?;
        Ok(())
    }

    /// 异步执行 原async
    pub async fn rasync<F>(&self, task: F) -> Result<(), Box<dyn std::error::Error>>
    where
        F: Future<Output = ()> + Send + 'static,
    {
        self.async_executor.spawn(task).await?;
        Ok(())
    }

    /// 异步执行
    pub async fn async_with_result<F, T>(&self, task: F) -> Result<T, Box<dyn std::error::Error>>
    where
        F: Future<Output = T> + Send + 'static,
        T: Send + 'static,
    {
        let result = self.async_executor.spawn(task).await?;
        Ok(result)
    }

    /// 尝试异步执行
    pub async fn async_and_try<F>(&self, task: F) -> Result<(), Box<dyn std::error::Error>>
    where
        F: FnOnce() + Send + 'static,
    {
        let task = tokio::task::spawn_blocking(move || Self::run_and_try(task));
        task.await?;
        Ok(())
    }

    /// 延迟执行
    pub fn delay<F>(&self, task: F, millis: u64) -> tokio::task::JoinHandle<()>
    where
        F: FnOnce() + Send + 'static,
    {
        let duration = Duration::from_millis(millis);
        tokio::task::spawn(async move {
            sleep(duration).await;
            task();
        })
    }

    /// 延迟执行并重复
    pub fn delay_and_repeat<F>(&self, task: F, millis: u64) -> tokio::task::JoinHandle<()>
    where
        F: Fn() + Send + 'static + Copy,
    {
        let duration = Duration::from_millis(millis);
        tokio::task::spawn(async move {
            loop {
                sleep(duration).await;
                task();
            }
        })
    }

    /// 定时任务
    pub fn schedule_at_fixed_rate<F>(&self, task: F, initial_delay: u64, millis_period: u64) -> tokio::task::JoinHandle<()>
    where
        F: Fn() + Send + 'static + Copy,
    {
        let initial_duration = Duration::from_millis(initial_delay);
        let period_duration = Duration::from_millis(millis_period);
        tokio::task::spawn(async move {
            sleep(initial_duration).await;
            let mut interval = tokio::time::interval(period_duration);
            loop {
                interval.tick().await;
                task();
            }
        })
    }

    /// 定时任务
    pub fn schedule_with_fixed_delay<F>(&self, task: F, initial_delay: u64, millis_delay: u64) -> tokio::task::JoinHandle<()>
    where
        F: Fn() + Send + 'static + Copy,
    {
        let initial_duration = Duration::from_millis(initial_delay);
        let delay_duration = Duration::from_millis(millis_delay);
        tokio::task::spawn(async move {
            sleep(initial_duration).await;
            loop {
                task();
                sleep(delay_duration).await;
            }
        })
    }

    /// 获取毫秒数（基于 nano）
    pub fn milli_second_from_nano() -> u64 {
        Instant::now().elapsed().as_millis() as u64
    }
}

